package hotel.meituan.oversea.biz.task;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import hotel.base.oversea.constant.CallbackConstants;
import hotel.base.oversea.constant.CommonConstants;
import hotel.base.oversea.constant.CommonUrlConstants;
import hotel.base.oversea.constant.MeituanConstants;
import hotel.base.oversea.constant.enums.MessageEnums;
import hotel.base.oversea.dto.meituan.*;
import hotel.base.oversea.utils.*;
import hotel.base.oversea.vo.meituan.request.goods.*;
import hotel.base.oversea.vo.meituan.request.room.MtHotelRealRoomVo;
import hotel.base.oversea.vo.meituan.response.goods.*;
import hotel.meituan.oversea.api.entity.*;
import hotel.meituan.oversea.api.vo.switchs.ProductNewAddVo;
import hotel.meituan.oversea.api.vo.up.response.hotel.MtHotelDetailVo;
import hotel.meituan.oversea.biz.config.service.RedisService;
import hotel.meituan.oversea.biz.mapper.*;
import hotel.meituan.oversea.biz.service.MtHotelGoodsService;
import hotel.meituan.oversea.biz.service.MtHotelRoomNameService;
import hotel.meituan.oversea.biz.service.MtHotelService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.RestTemplate;
import tk.mybatis.mapper.entity.Example;

import java.text.ParseException;
import java.util.*;
import java.util.concurrent.TimeUnit;


@Slf4j
@Component
public class MeituanFindMtGoodsCheckUpDownTask {
    @Autowired
    private MtHotelGoodsService mtHotelGoodsService;

    @Autowired
    private MtHotelRoomNameService mtHotelRoomNameService;

    @Autowired
    private MtHotelGoodsMapper mtHotelGoodsMapper;
    @Autowired
    private MtHotelMapper mtHotelMapper;
    @Autowired
    private MtHotelDetailOperLogMapper mtHotelDetailOperLogMapper;

    @Autowired
    private MtHotelGoodsBreakfastMapper mtHotelGoodsBreakfastMapper;

    @Autowired
    private MtHotelGoodsUpDownLogMapper mtHotelGoodsUpDownLogMapper;

    @Autowired
    private RedisService redisService;

    @Autowired
    private MtHotelService mtHotelService;

    @Autowired
    private RestTemplate restTemplate;

    public static void main(String[] args) {
        String partTimeHourBasic = "03";
        String thisHour =  DateUtil.formatDate("2020-10-09 03:01:03","HH");
        System.out.printf("==aa"+thisHour);
        if(Integer.valueOf(partTimeHourBasic)==Integer.valueOf(thisHour)){
            System.out.printf("==1");
        }
    }

    @Async
    public void executTenHotels(Map<Long,List<MtHotelRealRoomVo>> oneHotelRoomInfosDataArray,Map<String,MtHotelDetailVo> hotelsMap,List<String> tenUpHotelsJsonList,String timestampIndex){//酒店id  产品+房型
        log.info(" {} >>>>>>>>> 异步线程 MeituanFindMtGoodsCheckUpDownTask  开始执行时间：{}，tenUpHotelsJsonList={}",timestampIndex,DateUtil.getNowTime(),GsonUtils.GsonString(tenUpHotelsJsonList));

        if(null != redisService.get(MeituanConstants.REDIS_KEY_CHECK_BASIC_JOB_THREAD_STOP)){
            log.info(timestampIndex+" findMtGoodsCheckUpDown BasicMtGoodsInfoCheckUpdateJob_stop  程序停止跑校验上架酒店产品上下线");
            return;
        }

        //mtHotelGoodsService.findMtGoodsCheckUpDown();
        //log.info(" {} >>>>>>>>> 异步线程 MeituanFindMtGoodsCheckUpDownTask  执行结束时间：{}",timestamp,DateUtil.getNowTime());

        String expkey = "check_up_hotel_goods_new_data_05";
        if(null != redisService.get("findMtGoodsCheckUpDown_expkey")){
            expkey = (String)redisService.get("findMtGoodsCheckUpDown_expkey");
        }
        //美团整点一次判断静态信息并且push到待保存队列（每天保存一次产品静态信息）--》静态信息涉及产品静态信息和酒店静态信息 先push到队列，等待另一个定时器处理保存到数据库表
        boolean updateHotelBasicInfoOneDayOneCount = false;
        if(timestampIndex.contains("updateBasicDayOneCount")){
            //美团凌晨1点更新产品静态信息，该时间点进入查询产品静态信息将会对产品静态信息push到队列中
            // 每天一次保存更新静态信息中：不去操作一些需要实时性的东西：比如：失效产品校验（这个校验的比对数据来源从缓存）
            //房型的失效和新增可以在每天一次更新保存静态信息中（pop酒店信息保存方法中同时处理房型失效和新增）
            updateHotelBasicInfoOneDayOneCount = true;
        }

        Integer downCount = 0;
        Map<String,List<String>> hotelGoodsFail = new HashMap();

        Integer addCount = 0;
        Map<String,List<String>> hotelGoodsAdd = new HashMap();

        Integer bfCount = 0;
        Map<String,List<String>> hotelGoodsBf = new HashMap();

        log.info("executeFindMtGoodsCheckUpDown upList "+GsonUtils.GsonString(tenUpHotelsJsonList));
        if(null != tenUpHotelsJsonList && tenUpHotelsJsonList.size()>0){
            log.info("当前线程 进来 酒店待查询数量={}",tenUpHotelsJsonList.size());
            //构建酒店ids集合
            List<Long> hotelIdsArray = new ArrayList<>();
            Map<String,Map<String,String>> swTenHotelGoodsMap = new HashMap<>();
            swTenHotelGoodsMap = checkBuildSwHotesData(swTenHotelGoodsMap,hotelIdsArray,tenUpHotelsJsonList,expkey,timestampIndex);
            log.info("构建数据后 当前线程 酒店待查询数量={},hotelIdsArray={}",tenUpHotelsJsonList.size(),GsonUtils.GsonString(hotelIdsArray));

            Result mtGoodsResult = null;
            Map<String,String> apiReturnHotelMap = new HashMap();//如果酒店是失效的，则这个酒店接口不返回该酒店数，
            try{
                log.info("查询的酒店hotelIdsArray={}",GsonUtils.GsonString(hotelIdsArray));
                /**
                 * 对上架的酒店查询最新产品信息（内容包含返回假的房型id，需要即时查询酒店接口得到对应最新的真的房型id--》这时候对最新realRoomId和本地库表比较或者和缓存比较（携程保存产品对应roomid），看是否出现变更）
                 */
                mtGoodsResult = mtHotelGoodsService.getTendHotelGoodsInfoForJob(hotelIdsArray);
                if(mtGoodsResult.getCode()!=CommonConstants.SUCCESS){
                    log.info(timestampIndex+" rp接口失败,hotelIdsArray={}, mtGoodsResult={}",GsonUtils.GsonString(hotelIdsArray),GsonUtils.GsonString(mtGoodsResult));
                    return;
                }
                MtHotelGoodsVo mtHotelGoodsVo = null;
                if(null != mtGoodsResult.getData()){
                    mtHotelGoodsVo = GsonUtils.objToBean(mtGoodsResult.getData(),MtHotelGoodsVo.class);
                }

                log.info(timestampIndex+" findMtGoodsCheckUpDown 查询所有酒店后，接口返回={}",GsonUtils.GsonString(mtHotelGoodsVo));
                if(null != mtHotelGoodsVo && mtHotelGoodsVo.getHotelGoods().size()>0){//接口返回数量可能小于等于10，因为如果酒店下线了就没有东西返回
                    log.info(timestampIndex+" findMtGoodsCheckUpDown 查询所有酒店后，接口返回size={}",mtHotelGoodsVo.getHotelGoods().size());
                    List<MtHotelGoodsChildInfoVo> hotelGoods = mtHotelGoodsVo.getHotelGoods();
                    //比对 携程上架产品  是否在 在最新的产品里（美团接口根据时间段查询产品信息默认查询未来30天）
                    for (MtHotelGoodsChildInfoVo oneHotel:hotelGoods){//接口返回数量可能小于等于10，因为如果酒店下线了就没有东西返回

                        if(null == oneHotelRoomInfosDataArray.get(Long.valueOf(oneHotel.getHotelId()))){
                            continue;
                        }

                        String thisMtHotelId = String.valueOf(oneHotel.getHotelId());

                        //【缓存Rp数据】组装携程需要数据--携程再次校验被下架酒店产品-保存rp接口酒店产品数据到缓存
                        redisService.setUnit(CommonConstants.SWITCH_MT_HOTEL_RP_GOODS_INFO_DATA_JOB_PUSH+thisMtHotelId,GsonUtils.GsonString(oneHotel),1L,TimeUnit.DAYS);

                        List<MtHotelRealRoomVo> oneHotelsRoomInfo = oneHotelRoomInfosDataArray.get(thisMtHotelId);//该酒店的物理房型信息


                        Map<String, MtHotelGoodsBaseInfoVo> newOneHotelOneGoodsMap = new HashMap<>();
                        Map<String,String> newThisHotelGoodsRoomInfoMap = new HashMap<>();
                        List<MtHotelGoodsBaseInfoVo> oneHotelgoodsData = oneHotel.getGoods();

                        List<String> addGoods = new ArrayList<>();
                        List<String> downGoods = new ArrayList<>();
                        List<String> bfGoods = new ArrayList<>();

                        apiReturnHotelMap.put(thisMtHotelId,thisMtHotelId);

                        if(null != oneHotelgoodsData && oneHotelgoodsData.size()>0){
                            MtHotelDetailVo mtHotelDetailVo = hotelsMap.get(thisMtHotelId);
                            if(updateHotelBasicInfoOneDayOneCount){//每天一次更新酒店信息
                                if(null != mtHotelDetailVo){
                                    //保存到缓存队列，缓存酒店信息，每天凌晨一次更新
                                    redisService.lPush(MeituanConstants.REDIS_QUEUE_SAVE_BASIC_HOTEL_DETAILS_INFO,GsonUtils.GsonString(mtHotelDetailVo));
                                }
                            }
                            if(null != mtHotelDetailVo){//有可能这时候查询出来的酒店信息为空，也是属于下线
                                //遍历这家酒店的所有最新产品，判断存在哪些是我们需要的产品

                                //校验接口返回的所有最新当前酒店产品数据（1、并且校验非全日房产品是否在上架的产品中，是则为失效，push到队列中）
                                Map<String,String> notFullDayGoodsMap = new HashMap<>();
                                Map<String,String> changeRGoods = new HashMap<>();
                                Map<String,String> breakfastMap = new HashMap<>();
                                Map<String,String> idcardmap = new HashMap<>();
                                checkOneHotelGoodsInfo(oneHotelsRoomInfo,mtHotelDetailVo,oneHotelgoodsData,thisMtHotelId,newThisHotelGoodsRoomInfoMap,newOneHotelOneGoodsMap,swTenHotelGoodsMap,notFullDayGoodsMap,changeRGoods,updateHotelBasicInfoOneDayOneCount,breakfastMap,idcardmap);

                                //上面过滤完数据，下面进行  失效 和 新增判断

                                log.info(timestampIndex+" findMtGoodsCheckUpDown newThisHotelGoodsRoomInfoMap.size()={} ",newThisHotelGoodsRoomInfoMap.size());
                                if(newThisHotelGoodsRoomInfoMap.size()>0){

                                    //2、校验携程上架产品，是否已不存在在酒店最新产品中，是则为失效push到队列中
                                    checkIsFailurePushQueue(thisMtHotelId,swTenHotelGoodsMap,newThisHotelGoodsRoomInfoMap,downCount,downGoods,timestampIndex,notFullDayGoodsMap,changeRGoods,breakfastMap,idcardmap);
                                    //downCount 方法内部改变 外部没有变化，需再set


                                    if(updateHotelBasicInfoOneDayOneCount){
                                        ///3、每天整点一次判断早餐等静态信息  对比本地库表，校验产品是否存在新增
                                        checkLocalDataIsAddProductPushQueue(thisMtHotelId,newThisHotelGoodsRoomInfoMap,newOneHotelOneGoodsMap,
                                                addCount,addGoods,bfCount,bfGoods,timestampIndex);

                                        //4、当前不做保存，先保存到队列，定时器慢慢消费掉。（比较结束后，更新本地库表信息（库表信息只能这边更新，其他不可更新，要作为比较用））
                                        //mtHotelGoodsService.saveMtGoodsData(null,mtHotelGoodsVo);
                                        redisService.lPush(MeituanConstants.REDIS_QUEUE_SAVE_BASIC_HOTEL_GOODS_INFO,GsonUtils.GsonString(mtHotelGoodsVo));
                                    }

                                }else{
                                    log.error("findMtGoodsCheckUpDown  异常   美团api未查询到酒店 全日房产品：mtHotelId={},",thisMtHotelId);

                                    //该酒店有返回产品数据，但是没有全日房产品，则当前上架产品全部下架，我们只上架全日房产品
                                    Map<String,String> thisOneSwHotelGoodsInfoMap = swTenHotelGoodsMap.get(thisMtHotelId);
                                    oneHotelNoneGoodsBuildQueueFailVo(thisOneSwHotelGoodsInfoMap,thisMtHotelId,timestampIndex);
                                }
                            }
                        }else{
                            log.error("findMtGoodsCheckUpDown异常   该酒店产品信息为空：thisMtHotelId={},mtGoodsResult={}",thisMtHotelId,GsonUtils.GsonString(mtGoodsResult));
                            /*Map<String,String> thisOneSwHotelGoodsInfoMap = swTenHotelGoodsMap.get(thisMtHotelId);
                            oneHotelNoneGoodsBuildQueueFailVo(thisOneSwHotelGoodsInfoMap,thisMtHotelId,timestampIndex);*///不列入失效，，可能只是请求频繁导致的rp返回产品信息为空

                        }

                        if(null != downGoods && downGoods.size()>0){
                            hotelGoodsFail.put(thisMtHotelId,downGoods);
                            downCount += downGoods.size();
                            downGoods = new ArrayList<>();
                        }

                        if(null != hotelGoodsBf && hotelGoodsBf.size()>0){
                            hotelGoodsBf.put(thisMtHotelId,bfGoods);
                            bfCount += bfGoods.size();
                            bfGoods = new ArrayList<>();
                        }

                        if(null != hotelGoodsAdd && hotelGoodsAdd.size()>0){
                            hotelGoodsAdd.put(thisMtHotelId,addGoods);
                            addCount += addGoods.size();
                            addGoods = new ArrayList<>();
                        }

                        redisService.setUnit(expkey+thisMtHotelId,1,30L, TimeUnit.MINUTES);//查询校验过的酒店 下次不再校验  失效时间2个小时，该方法被定时器调用一天调用两次
                        log.info(timestampIndex+" findMtGoodsCheckUpDown  "+DateUtil.getCurrTime()+" 一家酒店结束：thisMtHotelId={}",thisMtHotelId);
                    }

                }else{
                    log.error("findMtGoodsCheckUpDown异常   美团api返回产品信息为空十家酒店无数据：hotelIdsArray={},mtGoodsResult={}",GsonUtils.GsonString(hotelIdsArray),GsonUtils.GsonString(mtGoodsResult));

                }

                //校验是否有酒店 没有产品返回则增加产品价格日历接口校验是否也为空，为空则为失效（该酒店可能是下线了）
                if(mtGoodsResult.getCode()==CommonConstants.SUCCESS){//rp接口调用成功情况下再去做判断
                    List<Long> isNullRpHotelsQuery = new ArrayList<>();
                    for(Map.Entry sw:swTenHotelGoodsMap.entrySet()) {
                        String swHotelId = (String) sw.getKey();
                        if (null == apiReturnHotelMap.get(swHotelId)) {
                            isNullRpHotelsQuery.add(Long.valueOf(swHotelId));
                            log.info("checkHotelGoodsFail    该酒店产品信息为空：thisMtHotelId={},mtGoodsResult={}",swHotelId,GsonUtils.GsonString(mtGoodsResult));
                        }
                    }
                    if(null != isNullRpHotelsQuery && isNullRpHotelsQuery.size()>0) {
                        Map<String, String> nullRpHotelsAndPriIsNull = new HashMap<>();
                        String start = DateUtil.formatDate(DateUtil.addDay(DateUtil.getCurrTime(), 1), "yyyy-MM-dd");
                        String end = DateUtil.formatDate(DateUtil.addDay(start, 1), "yyyy-MM-dd");
                        Result resultPr = mtHotelGoodsService.saveGetMtHotelGoodsPrice(isNullRpHotelsQuery, null, start, end, null);
                        if (resultPr.getCode() == CommonConstants.SUCCESS) {
                            List<MtHotelGoodsPriceBaseVo> mtHotelGoodsPriceBaseVoList = (List<MtHotelGoodsPriceBaseVo>) resultPr.getData();
                            if (null == mtHotelGoodsPriceBaseVoList || mtHotelGoodsPriceBaseVoList.size() == 0) {
                                for (Long p : isNullRpHotelsQuery) {
                                    nullRpHotelsAndPriIsNull.put(String.valueOf(p), String.valueOf(p));
                                }
                            }else{
                                Map<String,String> priApiHotel = new HashMap<>();
                                for (MtHotelGoodsPriceBaseVo b:mtHotelGoodsPriceBaseVoList){
                                    priApiHotel.put(String.valueOf(b.getHotelId()),String.valueOf(b.getHotelId()));
                                }
                                for (Long p:isNullRpHotelsQuery){
                                    if(null == priApiHotel.get(String.valueOf(p))){
                                        nullRpHotelsAndPriIsNull.put(String.valueOf(p), String.valueOf(p));
                                    }
                                }
                            }
                        }

                        for (int i = 0; i < isNullRpHotelsQuery.size(); i++) {
                            String swHotelId = String.valueOf(isNullRpHotelsQuery.get(i));
                            if(null != nullRpHotelsAndPriIsNull.get(swHotelId)){
                                //1、rp没有，，价格日历接口也没有数据 - --》酒店下线
                                log.info("静态信息校验，酒店下线了！rp接口和价格日历接口都没有数据，酒店id="+swHotelId);
                                //SendUtils.dingMsgNotLog("[FP-JOB-CHECK-HOTEL-DOWN]",DateUtil.getCurrTime()+" 静态信息校验，酒店下线了！rp接口和价格日历接口都没有数据，酒店id="+swHotelId,MessageEnums.genre.FP_HOTEL_INFO_NOTICY.getCode(),restTemplate);
                                String swResult = requestSwitchsUpdateHotel(Integer.valueOf(swHotelId),0);
                                try{
                                    MtHotelDetailOperLog mtHotelDetailOperLog = new MtHotelDetailOperLog();
                                    mtHotelDetailOperLog.setMtHotelId(swHotelId);
                                    mtHotelDetailOperLog.setRemark("价格接口null");
                                    mtHotelDetailOperLog.setCreateTime(new Date());
                                    mtHotelDetailOperLog.setState(0);
                                    mtHotelDetailOperLog.setId(StringUtil.getUUID());
                                    mtHotelDetailOperLog.setType(2);
                                    mtHotelDetailOperLogMapper.insert(mtHotelDetailOperLog);
                                    redisService.remove(CommonConstants.SWITCH_MT_HOTEL_DETAIL_INFO_DATA_JOB_PUSH+swHotelId);
                                    redisService.remove(CommonConstants.SWITCH_MT_ONE_HOTEL_ROOMS_REDIS+swHotelId);
                                    redisService.remove(CommonConstants.SWITCH_MT_HOTEL_RP_GOODS_INFO_DATA_JOB_PUSH+swHotelId);
                                }catch (Exception e){
                                    e.printStackTrace();
                                }
                                try{
                                    MtHotel mtHotel = new MtHotel();
                                    mtHotel.setType(2);
                                    mtHotel.setModifyTime(new Date());
                                    Example example = new Example(MtHotel.class);
                                    Example.Criteria criteria = example.createCriteria();
                                    criteria.andEqualTo("mtHotelId",swHotelId);
                                    mtHotelMapper.updateByExampleSelective(mtHotel,example);
                                }catch (Exception e){
                                    log.info("酒店下线更新酒店库表状态失败 id={},msg={}",swHotelId,e.getMessage());
                                    e.printStackTrace();
                                }
                                //oneHotelNoneGoodsBuildQueueFailVo(thisOneSwHotelGoodsMap,swHotelId,timestampIndex);
                            }else{
                                //当前酒店未获取到酒店详情，则该酒店很大可能已下架
                                //再次查询酒店详情接口 看是否返回空
                                List<Long> checkThisHotel = new ArrayList<>();
                                checkThisHotel.add(Long.valueOf(swHotelId));
                                Result cr = mtHotelService.getMtHotelDetail(checkThisHotel);
                                if(cr.getCode()==CommonConstants.SUCCESS){
                                    List<MtHotelDetailVo> voList = null;
                                    if(null != cr.getData()){
                                        voList = (List<MtHotelDetailVo>)cr.getData();
                                    }
                                    if(null == voList || voList.size()==0){
                                        log.info("静态信息校验，酒店下线了！再次调用详情接口验证酒店id="+swHotelId);
                                        try{
                                            MtHotelDetailOperLog mtHotelDetailOperLog = new MtHotelDetailOperLog();
                                            mtHotelDetailOperLog.setMtHotelId(swHotelId);
                                            mtHotelDetailOperLog.setRemark("详情接口null");
                                            mtHotelDetailOperLog.setCreateTime(new Date());
                                            mtHotelDetailOperLog.setState(0);
                                            mtHotelDetailOperLog.setId(StringUtil.getUUID());
                                            mtHotelDetailOperLog.setType(2);
                                            mtHotelDetailOperLogMapper.insert(mtHotelDetailOperLog);
                                            redisService.remove(CommonConstants.SWITCH_MT_HOTEL_DETAIL_INFO_DATA_JOB_PUSH+swHotelId);
                                            redisService.remove(CommonConstants.SWITCH_MT_ONE_HOTEL_ROOMS_REDIS+swHotelId);
                                            redisService.remove(CommonConstants.SWITCH_MT_HOTEL_RP_GOODS_INFO_DATA_JOB_PUSH+swHotelId);
                                        }catch (Exception e){
                                            e.printStackTrace();
                                        }
                                        try{
                                            MtHotel mtHotel = new MtHotel();
                                            mtHotel.setType(2);
                                            mtHotel.setModifyTime(new Date());
                                            Example example = new Example(MtHotel.class);
                                            Example.Criteria criteria = example.createCriteria();
                                            criteria.andEqualTo("mtHotelId",swHotelId);
                                            mtHotelMapper.updateByExampleSelective(mtHotel,example);
                                        }catch (Exception e){
                                            log.info("酒店下线更新酒店库表状态失败 id={},msg={}",swHotelId,e.getMessage());
                                            e.printStackTrace();
                                        }

                                        //SendUtils.dingMsgNotLog("[JOB-CHECK-HOTEL-DOWN]",DateUtil.getCurrTime()+" 静态信息校验，酒店下线了！详情接口没有数据，酒店id="+swHotelId,MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);
                                        String swResult = requestSwitchsUpdateHotel(Integer.valueOf(swHotelId),0);
                                        //oneHotelNoneGoodsBuildQueueFailVo(thisOneSwHotelGoodsMap,swHotelId,timestampIndex);
                                    }
                                }
                            }
                        }
                    }
                }else{
                    log.info("checkHotelGoodsFail    酒店产品Rp接口调用失败：hotelIdsArray={},mtGoodsResult={}",GsonUtils.GsonString(hotelIdsArray),GsonUtils.GsonString(mtGoodsResult));
                }



            }catch (Exception e){
                log.error("findMtGoodsCheckUpDown 异常 getMessage="+e.getMessage()+",tenUpHotelsJsonList="+tenUpHotelsJsonList);
                log.info("产品失效新增校验停止线程");
                redisService.setUnit(MeituanConstants.REDIS_KEY_CHECK_BASIC_JOB_THREAD_STOP,1,20L,TimeUnit.SECONDS);
                SendUtils.dingMsgNotLog("产品失效新增校验，程序异常停止请关注！ ",DateUtil.getCurrTime()+" 异常信息："+e.getMessage(),MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);
                e.printStackTrace();
            }
        }else{
            log.info(timestampIndex+" findMtGoodsCheckUpDown   getUpHotelGoodsData 未找到携程上架数据");
        }
        log.info(timestampIndex+" findMtGoodsCheckUpDown  结束时间 "+DateUtil.getCurrTime()+" 十家一次接口存在产品变化：新增产品："+GsonUtils.GsonString(hotelGoodsAdd)+"，失效产品："+GsonUtils.GsonString(hotelGoodsFail)+"，变化早餐产品："+GsonUtils.GsonString(hotelGoodsBf));
        if(addCount>0 || downCount>0 || bfCount>0){
            Integer downCountHotels = 0;
            if(downCount>0){
                downCountHotels = 1;
            }
            SendUtils.dingMsg("产品静态信息更新，产品失效新增校验 ",DateUtil.getCurrTime()+" 该次线程存在产品变化：[ 新增产品："+GsonUtils.GsonString(hotelGoodsAdd)+"] ，，，， [ 失效产品："+GsonUtils.GsonString(hotelGoodsFail)+" 失效产品数量为："+downCount+"，增加队列 "+downCountHotels+" ] ，，，，[ 变化早餐产品："+GsonUtils.GsonString(hotelGoodsBf)+" ]", MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);

        }

        if(timestampIndex.contains("lastTask")){
            try {
                Thread.sleep(15000);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
            String goodsData = timestampIndex.split("_")[0];
            String hotels = timestampIndex.split("_")[1];
            SendUtils.dingMsg("结束一轮上架酒店产品校验！当前可‘开启’携程定时器处理产品队列 ",DateUtil.getCurrTime()+" (上架酒店："+hotels+" 售卖房型数据："+goodsData
                    +") 新增队列："+redisService.queueSize(MeituanConstants.REDIS_QUEUE_HOTEL_ADD_GOODS_JSON_KEY)
                    +" 失效队列："+redisService.queueSize(MeituanConstants.REDIS_QUEUE_HOTEL_DOWN_GOODS_JSON_KEY)
                    +" 早餐队列："+redisService.queueSize(MeituanConstants.REDIS_QUEUE_HOTEL_BREAKFAST_JSON_KEY)
                    +"   (可能还存在未结束线程队列大于当前)  ", MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);
        }


    }

    public Map<String,Map<String,String>> checkBuildSwHotesData(Map<String,Map<String,String>> swTenHotelGoodsMap,List<Long> hotelIdsArray,List<String> tenUpHotelsJsonList,String expkey,String timestampIndex) {
        for (String oneHotelGoodsJson:tenUpHotelsJsonList){
            Map<String,Map<String,String>> oneHotelMap = GsonUtils.GsonToMaps(oneHotelGoodsJson);
            String thisMtHotelId = null;
            for (Map.Entry one:oneHotelMap.entrySet()){
                thisMtHotelId = (String)one.getKey();

                //遍历携程上架的美团酒店
               /* if(null != redisService.get(expkey+thisMtHotelId)){
                    log.info(timestampIndex+" findMtGoodsCheckUpDown 该酒店最近1小时内校验过产品 hotelId={}",thisMtHotelId);
                }*/
                hotelIdsArray.add(Long.valueOf(thisMtHotelId));
                if(null == swTenHotelGoodsMap.get(thisMtHotelId)){
                    swTenHotelGoodsMap.put(thisMtHotelId,(Map<String,String>)one.getValue());
                    log.info("checkBuildSwHotesData thisMtHotelId={}",thisMtHotelId);
                }
            }
        }
        return swTenHotelGoodsMap;
    }

    /**
     * 1、校验携程上架产品，是否已不存在在酒店最新产品中，是则为失效  2、全日->钟点房 为失效  3、产品房型id变化  为失效
     * @param thisMtHotelId
     * @param swTenHotelGoodsMap
     * @param newThisHotelGoodsRoomInfoMap
     * @param downCount
     * @param downGoods
     * @param timestampIndex
     */
    private void checkIsFailurePushQueue(String thisMtHotelId,Map<String,Map<String,String>> swTenHotelGoodsMap,Map<String,String> newThisHotelGoodsRoomInfoMap,int downCount,List<String> downGoods,
                                         String timestampIndex,Map<String,String> notFullDayGoodsMap,Map<String,String> changeRGoods,Map<String,String> breakfastMap,Map<String,String> idcardmap) {

        ProductFailureVo oneHotelProductFailureVo = new ProductFailureVo();
        List<ProductFailureDetailVo> goodsDataFailure = new ArrayList<>();
        oneHotelProductFailureVo.setMtHotelId(Integer.valueOf(thisMtHotelId));
        //遍历携程上架酒店产品
        Map<String,String> thisOneSwHotelGoodsMapData = swTenHotelGoodsMap.get(thisMtHotelId);//swTenHotelGoodsMap=Map<String,Map<String,String>> -->Map<酒店id,Map<产品id,房型id>>
        for (Map.Entry oneSwitchsGoods:thisOneSwHotelGoodsMapData.entrySet()){
            String swGoodsId = (String) oneSwitchsGoods.getKey();
            if(null == newThisHotelGoodsRoomInfoMap.get(swGoodsId)){
                log.info("findMtGoodsCheckUpDown 符合为失效产品已不在最新查询的产品集合中 hotelId={},newGoodsId={}",thisMtHotelId,swGoodsId);
                downCount +=1;
                downGoods.add(swGoodsId);
                String roomId = (String)oneSwitchsGoods.getValue();
                ProductFailureDetailVo detailVo = buildOneGoodsFailureDetailVoSaveLog(swGoodsId,roomId,thisMtHotelId,"2");
                goodsDataFailure.add(detailVo);
            }
            //全日房变为钟点房 属于失效
            if(null != notFullDayGoodsMap && notFullDayGoodsMap.size()>0){
                if(null != notFullDayGoodsMap.get(swGoodsId)){
                    log.info("notFullDayGoodsMap 全日房变为钟点房，符合为失效产品 hotelId={},newGoodsId={}",thisMtHotelId,swGoodsId);
                    downCount +=1;
                    downGoods.add(swGoodsId);
                    String roomId = (String)oneSwitchsGoods.getValue();
                    ProductFailureDetailVo detailVo = new ProductFailureDetailVo();
                    detailVo.setGenre(0);
                    detailVo.setMtGoodId(Integer.valueOf(swGoodsId));
                    detailVo.setMtRoomId(Integer.valueOf(roomId));
                    goodsDataFailure.add(detailVo);
                }
            }
            //房型id发送变化 属于失效
            if(null != changeRGoods && changeRGoods.size()>0){
                if(null != changeRGoods.get(swGoodsId)){
                    log.info("changeRGoods 产品房型id变化，符合为失效产品 hotelId={},newGoodsId={}",thisMtHotelId,swGoodsId);
                    downCount +=1;
                    downGoods.add(swGoodsId);
                    String roomId = (String)oneSwitchsGoods.getValue();
                    ProductFailureDetailVo detailVo = new ProductFailureDetailVo();
                    detailVo.setGenre(0);
                    detailVo.setMtGoodId(Integer.valueOf(swGoodsId));
                    detailVo.setMtRoomId(Integer.valueOf(roomId));
                    goodsDataFailure.add(detailVo);
                }
            }
            //因早餐而失效
            if(null != breakfastMap && breakfastMap.size()>0){
                if(null != breakfastMap.get(swGoodsId)){
                    log.info("breakfastMap 因早餐而失效，符合为失效产品 hotelId={},newGoodsId={}",thisMtHotelId,swGoodsId);
                    downCount +=1;
                    downGoods.add(swGoodsId);
                    String roomId = (String)oneSwitchsGoods.getValue();
                    ProductFailureDetailVo detailVo = new ProductFailureDetailVo();
                    detailVo.setGenre(0);
                    detailVo.setMtGoodId(Integer.valueOf(swGoodsId));
                    detailVo.setMtRoomId(Integer.valueOf(roomId));
                    goodsDataFailure.add(detailVo);
                }
            }
            //因身份证而失效
            if(null != idcardmap && idcardmap.size()>0){
                if(null != idcardmap.get(swGoodsId)){
                    log.info("idcardmap 因身份证而失效，符合为失效产品 hotelId={},newGoodsId={}",thisMtHotelId,swGoodsId);
                    downCount +=1;
                    downGoods.add(swGoodsId);
                    String roomId = (String)oneSwitchsGoods.getValue();
                    ProductFailureDetailVo detailVo = new ProductFailureDetailVo();
                    detailVo.setGenre(0);
                    detailVo.setMtGoodId(Integer.valueOf(swGoodsId));
                    detailVo.setMtRoomId(Integer.valueOf(roomId));
                    goodsDataFailure.add(detailVo);
                }
            }
        }
        if(null != goodsDataFailure && goodsDataFailure.size()>0){
            oneHotelProductFailureVo.setGoods(goodsDataFailure);
            pushSwQueue(thisMtHotelId,GsonUtils.GsonString(oneHotelProductFailureVo),timestampIndex);
        }

    }

    public String requestSwitchsUpdateHotel(Integer mtHotelId,Integer status){
        //发起请求
        Map map = new HashMap();
        map.put("mtHotelId",mtHotelId);
        map.put("status",status);//状态 0 下线 1 上线
        log.info("requestSwitchsUpdateHotel请求="+ GsonUtils.GsonString(map));
        Result result = RestTemplateUtils.post(CommonUrlConstants.SWITCHS_ONLINE_HOST+"/switchCreateRoom/downHotel", JSON.toJSONString(map),restTemplate);
        if(result.getCode()!= CommonConstants.SUCCESS){
            SendUtils.dingMsg("[JOB-CHECK-HOTEL-DOWN]酒店下线了，调用携程修改接口失败 ","请求参数："+ JSON.toJSONString(map)+" 响应："+ JSON.toJSONString(result),MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);
        }else{
            log.info("requestSwitchsUpdateHotel响应="+ JSON.toJSONString(result)+",请求参数："+ JSON.toJSONString(map));
        }
        return JSON.toJSONString(result);

    }

    //校验接口返回的所有最新当前酒店产品数据
    // 内部包含校验产品房型id是否已变更，则push到失效队列，等待推送携程
    //内部包含校验 全日房是否已变更为钟点房，则push到失效产品队列，等待推送携程
    //针对上架酒店底下所有产品，该方法不做是否为上架产品判断，对所有产品先统一处理一遍
    public void checkOneHotelGoodsInfo(List<MtHotelRealRoomVo> oneHotelRoomInfos, MtHotelDetailVo hotelDetail, List<MtHotelGoodsBaseInfoVo> oneHotelgoodsData, String thisMtHotelId, Map newThisHotelGoodsRoomInfoMap, Map newOneHotelOneGoodsMap, Map<String,Map<String,String>> swTenHotelGoodsMap,
                                       Map<String,String> notFullDayGoodsMap, Map<String,String> changeRGoods, Boolean updateHotelBasicInfoOneDayOneCount, Map<String,String> breakfastMap, Map<String,String> idcardmap) {
        Map<String,String> thisOneSwHotelGoodsMapData = swTenHotelGoodsMap.get(thisMtHotelId);
        for (MtHotelGoodsBaseInfoVo thisHotelOneGoodsInfo:oneHotelgoodsData){

            List<MtHotelGoodsBookRuleVo> bookRules = thisHotelOneGoodsInfo.getBookRules();
            List<MtHotelGoodsCancelRuleVo> cancelRules = thisHotelOneGoodsInfo.getCancelRules();
            String thisGoodsId = thisHotelOneGoodsInfo.getGoodsId();
            Integer thisGoodsType = thisHotelOneGoodsInfo.getGoodsType();//1 全日房  2 钟点房

            Boolean needIdCard = thisHotelOneGoodsInfo.getNeedIdentityCard();//true 需要 false 不需要
            String thisGoodsSwExsiRoomId = null;

            thisGoodsSwExsiRoomId = (String)redisService.hmGet(CommonConstants.SWITCH_SELLING_THE_HOUSE_TYPE,thisMtHotelId+"_"+thisGoodsId);
            if(!ObjectUtils.isEmpty(thisGoodsSwExsiRoomId)){
                //log.info("checkOneHotelGoodsInfo 进入第二版 判断上架产品：thisGoodsId={},thisGoodsSwExsiRoomId={}",thisGoodsId,thisGoodsSwExsiRoomId);
            }else{
                thisGoodsSwExsiRoomId = (String)redisService.get(CommonConstants.SWITCH_SELLING_THE_HOUSE_TYPE+thisMtHotelId+"_"+thisGoodsId);
                //log.info("checkOneHotelGoodsInfo 进入第一版 判断上架产品：thisGoodsId={},thisGoodsSwExsiRoomId={}",thisGoodsId,thisGoodsSwExsiRoomId);
            }

            if(null != thisGoodsSwExsiRoomId && null != needIdCard && needIdCard){
                //SendUtils.dingMsgNotLog("[FAIL-IDCARD]","该产品需要身份证，列入失效产品队列，等待POP推送，酒店id="+thisMtHotelId+" 产品id="+thisGoodsId,MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);
                log.info("该产品需要身份证列入失效产品队列 hotelid={},needIdCard={}",thisMtHotelId,needIdCard);
                idcardmap.put(thisGoodsId,thisGoodsId);
                MtHotelGoodsUpDownLog mtHotelGoodsUpDownLog = new MtHotelGoodsUpDownLog();
                mtHotelGoodsUpDownLog.setId(StringUtil.getUUID());
                mtHotelGoodsUpDownLog.setMtHotelId(thisMtHotelId);
                mtHotelGoodsUpDownLog.setMtGoodsId(thisGoodsId);
                mtHotelGoodsUpDownLog.setMtRoomId(null);
                mtHotelGoodsUpDownLog.setRemark("needIdCard="+needIdCard);
                mtHotelGoodsUpDownLog.setCreateTime(new Date());
                mtHotelGoodsUpDownLog.setSource("9");
                mtHotelGoodsUpDownLog.setType("0");
                mtHotelGoodsUpDownLogMapper.insert(mtHotelGoodsUpDownLog);
            }else{
                if(thisGoodsType==1){
                    //全日房
                    List<MtHotelGoodsBaseRoomVo> thisGoodsRoomInfoArr = thisHotelOneGoodsInfo.getRoomInfoList();
                    if(null != thisGoodsRoomInfoArr && thisGoodsRoomInfoArr.size()>0){
                        String thisGoodsFalseOrTrueRoomId = thisGoodsRoomInfoArr.get(0).getRoomId();//roomid=从room集合信息中（美团实际只返回一个）（产品接口返回）
                        if(thisGoodsRoomInfoArr.size()>1){
                            //上游标识每个产品只对应一个房间信息,但返回的是list，特殊处理
                            log.error("findMtGoodsCheckUpDown ////////////////MTAPIERROR///////////////////酒店产品列表接口数据异常 goodsBaseRoom size >1");
                        }else{
                            if(null != hotelDetail.getRoomInfos() && hotelDetail.getRoomInfos().size()>0){
                                log.info("getdetail酒店id={},获取酒店信息room信息={}",thisMtHotelId,GsonUtils.GsonString(hotelDetail));
                                String thisRealRoomId = mtHotelRoomNameService.goodsInfosCheckReturnGoodsRealRoomId(oneHotelRoomInfos,hotelDetail,thisMtHotelId,thisGoodsRoomInfoArr,thisGoodsId);
                                if(!ObjectUtil.isEmpty(thisRealRoomId)){
                                    thisHotelOneGoodsInfo.setRoomId(thisRealRoomId);//set到外层额外roomid字段
                                }else{
                                    thisHotelOneGoodsInfo.setRoomId(thisGoodsFalseOrTrueRoomId);//set到外层额外roomid字段
                                }
                                if(null != thisGoodsSwExsiRoomId){
                                    if(null != thisRealRoomId){
                                        Boolean nextCheck = true;
                                        if(!thisGoodsSwExsiRoomId.equals(thisRealRoomId)){//产品的房型id变更  这个检验可以每2小时都校验  --》不同于房型失效和新增 每天一次，房型失效和新增是和本地数据比较的本地数据每天更新一次
                                            log.info("存在产品房型id变化 hotelid={},goodsId={}, thisGoodsSwExsiRoomId={},goodsBaseInfoVo.thisRealRoomId()={}",thisMtHotelId,thisGoodsId,thisGoodsSwExsiRoomId,thisRealRoomId);
                                            changeRGoods.put(thisGoodsId,thisRealRoomId);
                                            MtHotelGoodsUpDownLog mtHotelGoodsUpDownLog = new MtHotelGoodsUpDownLog();
                                            mtHotelGoodsUpDownLog.setId(StringUtil.getUUID());
                                            mtHotelGoodsUpDownLog.setMtHotelId(thisMtHotelId);
                                            mtHotelGoodsUpDownLog.setMtGoodsId(thisGoodsId);
                                            mtHotelGoodsUpDownLog.setMtRoomId(thisRealRoomId);
                                            mtHotelGoodsUpDownLog.setCreateTime(new Date());
                                            mtHotelGoodsUpDownLog.setRemark("产品接口返回room信息："+GsonUtils.GsonString(thisHotelOneGoodsInfo)+"，缓存roomid="+thisGoodsSwExsiRoomId);
                                            mtHotelGoodsUpDownLog.setSource("4");
                                            mtHotelGoodsUpDownLog.setType("0");
                                            mtHotelGoodsUpDownLogMapper.insert(mtHotelGoodsUpDownLog);
                                            nextCheck = false;
                                        }

                                        if(nextCheck){
                                            if(null != bookRules && bookRules.size()>0){
                                                MtHotelGoodsBookRuleVo mtHotelGoodsBookRuleVo = bookRules.get(0);
                                                if(mtHotelGoodsBookRuleVo.getRoomCountMin()>1 || mtHotelGoodsBookRuleVo.getSerialCheckinMin()>1){
                                                    log.info("携程预订房间数量 和 预订天数 大于1的  列入失效 goodsId:{},thisMtHotelId={}",thisGoodsId,thisMtHotelId);
                                                    //SendUtils.dingMsgNotLog("[FP-SUM-1]携程 上架产品预订房间数量或预订天数大于1，归列到失效产品！ "," 酒店id="+thisMtHotelId+" 产品id="+thisGoodsId+" rules信息="+GsonUtils.GsonString(mtHotelGoodsBookRuleVo),MessageEnums.genre.FP_HOTEL_INFO_NOTICY.getCode(),restTemplate);
                                                    idcardmap.put(thisGoodsId,thisGoodsId);
                                                    MtHotelGoodsUpDownLog mtHotelGoodsUpDownLog = new MtHotelGoodsUpDownLog();
                                                    mtHotelGoodsUpDownLog.setId(StringUtil.getUUID());
                                                    mtHotelGoodsUpDownLog.setMtHotelId(thisMtHotelId);
                                                    mtHotelGoodsUpDownLog.setMtGoodsId(thisGoodsId);
                                                    mtHotelGoodsUpDownLog.setMtRoomId(thisRealRoomId);
                                                    mtHotelGoodsUpDownLog.setCreateTime(new Date());
                                                    mtHotelGoodsUpDownLog.setRemark("rules："+GsonUtils.GsonString(mtHotelGoodsBookRuleVo)+"，缓存roomid="+thisGoodsSwExsiRoomId);
                                                    mtHotelGoodsUpDownLog.setSource("11");
                                                    mtHotelGoodsUpDownLog.setType("0");
                                                    mtHotelGoodsUpDownLogMapper.insert(mtHotelGoodsUpDownLog);
                                                }else{
                                                    /**
                                                     * 早餐类型：
                                                     * 0 不含早餐
                                                     * 1 含有breakfastNum份免费早餐
                                                     * 2 收费早餐
                                                     */
                                                    List<MtHotelGoodsBreakfastVo> thisNewGoodsBreakfastVos = thisHotelOneGoodsInfo.getBreakFast();
                                                    if(null != thisNewGoodsBreakfastVos && thisNewGoodsBreakfastVos.size()>0){
                                                        MtHotelGoodsBreakfastVo todayBreakfast = new MtHotelGoodsBreakfastVo();
                                                        if(thisNewGoodsBreakfastVos.size()>1){
                                                            log.info("早餐信息数量大于1，goodsId={},thisNewGoodsBreakfastVos={}",thisGoodsId,GsonUtils.GsonString(thisNewGoodsBreakfastVos));
                                                            for (int i = 0; i < thisNewGoodsBreakfastVos.size(); i++) {
                                                                MtHotelGoodsBreakfastVo b = thisNewGoodsBreakfastVos.get(i);
                                                                if(b.getInStartDate()!=0){
                                                                    Integer s = b.getInStartDate();
                                                                    Integer e = b.getInEndDate();
                                                                    String end = null;
                                                                    String start = null;
                                                                    try {
                                                                        start = DateUtil.parseStrYYYYMMDD(String.valueOf(s));
                                                                        end = DateUtil.parseStrYYYYMMDD(String.valueOf(e));
                                                                    } catch (ParseException e1) {
                                                                        e1.printStackTrace();
                                                                    }
                                                                    Map<String,String> days = DateUtil.getTwoDaysDay(String.valueOf(start),String.valueOf(end));
                                                                    if(null != days.get(DateUtil.getCurrTimeYmd("yyyy-MM-dd"))){
                                                                        log.info("早餐信息数量大于1，goodsId={},当前指定日期早餐规则，今日符合 start={}，end={}",thisGoodsId,start,end);
                                                                        //‘今天’属于指定时间的早餐
                                                                        todayBreakfast = b;
                                                                    }else{
                                                                        //‘今天’不属于指定时间的早餐，则一定是属于另一个 inStartDate = 0 这一组早餐规则
                                                                        if(i==0){
                                                                            todayBreakfast = thisNewGoodsBreakfastVos.get(1);
                                                                        }else{
                                                                            todayBreakfast = thisNewGoodsBreakfastVos.get(0);
                                                                        }
                                                                        log.info("早餐信息数量大于1，goodsId={},当前指定日期早餐规则，今日不符合选择0选项 todayBreakfast={}",thisGoodsId,GsonUtils.GsonString(todayBreakfast));
                                                                    }
                                                                    break;
                                                                }
                                                            }
                                                        }else{
                                                            todayBreakfast = thisNewGoodsBreakfastVos.get(0);
                                                        }
                                                        Integer thisNewGoodsNewBfType = todayBreakfast.getBreakfastType();
                                                        Integer thisNewGoodsNewBfNum = todayBreakfast.getBreakfastNum();

                                                        Integer hasBreakfastValueIsNum = null;//(Integer)redisService.get(CommonConstants.SWITCH_CREATE_ROOM_BREAKFAST+thisMtHotelId+"_"+thisGoodsId+"_1");//有存在值 说明是上架的有早餐产品 key=1有早餐  value=数量
                                                        Integer noBreakfastValueIsNum = null;//(Integer)redisService.get(CommonConstants.SWITCH_CREATE_ROOM_BREAKFAST+thisMtHotelId+"_"+thisGoodsId+"_0");//有存在值 说明是上架的无早餐产品 key=0无早餐  value=0

                                                        Integer breakfastNoOrYes = (Integer)redisService.hmGet(CommonConstants.SWITCH_CREATE_ROOM_BREAKFAST,thisMtHotelId+"_"+thisGoodsId);
                                                        if(!ObjectUtils.isEmpty(breakfastNoOrYes)){
                                                            if(breakfastNoOrYes ==0 ){
                                                                noBreakfastValueIsNum = 0;
                                                            }else if(breakfastNoOrYes >0 ){
                                                                hasBreakfastValueIsNum = breakfastNoOrYes;
                                                            }
                                                            //log.info("进入第二版 早餐规则：noBreakfastValueIsNum={}，hasBreakfastValueIsNum={}",noBreakfastValueIsNum,hasBreakfastValueIsNum);
                                                        }else{
                                                            noBreakfastValueIsNum = (Integer)redisService.get(CommonConstants.SWITCH_CREATE_ROOM_BREAKFAST+thisMtHotelId+"_"+thisGoodsId+"_0");
                                                            hasBreakfastValueIsNum = (Integer)redisService.get(CommonConstants.SWITCH_CREATE_ROOM_BREAKFAST+thisMtHotelId+"_"+thisGoodsId+"_1");
                                                            //log.info("进入第一版 早餐规则：noBreakfastValueIsNum={}，hasBreakfastValueIsNum={}",noBreakfastValueIsNum,hasBreakfastValueIsNum);
                                                        }


                                                        if(null != hasBreakfastValueIsNum){//如果当前产品是推送的有早餐，则进行校验,当前产品早餐是否变为  1、无早   2、早餐数量是否变更
                                                            if(1 != thisNewGoodsNewBfType){
                                                                SendUtils.dingMsgNotLog("[FAIL-BREAKFAST]","该产品早餐从有到无，列入失效产品队列，等待消费处理，酒店id="+thisMtHotelId+" 产品id="+thisGoodsId,MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);
                                                                log.info("存在早餐信息变化产品早餐从免费变为无早餐或者收费早餐 hotelid={},thisNewGoodsBreakfastVos={}",thisMtHotelId,GsonUtils.GsonString(thisNewGoodsBreakfastVos));
                                                                //早餐从免费变为 无早餐或者收费早餐，加入失效产品队列--》2020-11-24 携程早餐接口 单无双早都不给设置，相当于无效接口，后期不推送早餐修改。
                                                                breakfastMap.put(thisGoodsId,thisGoodsId);
                                                                MtHotelGoodsUpDownLog mtHotelGoodsUpDownLog = new MtHotelGoodsUpDownLog();
                                                                mtHotelGoodsUpDownLog.setId(StringUtil.getUUID());
                                                                mtHotelGoodsUpDownLog.setMtHotelId(thisMtHotelId);
                                                                mtHotelGoodsUpDownLog.setMtGoodsId(thisGoodsId);
                                                                mtHotelGoodsUpDownLog.setMtRoomId(thisRealRoomId);
                                                                mtHotelGoodsUpDownLog.setRemark("old="+1+",new="+thisNewGoodsNewBfType+",thisGoodsSwExsiRoomId="+thisGoodsSwExsiRoomId);
                                                                mtHotelGoodsUpDownLog.setCreateTime(new Date());
                                                                mtHotelGoodsUpDownLog.setSource("6");
                                                                mtHotelGoodsUpDownLog.setType("0");
                                                                mtHotelGoodsUpDownLogMapper.insert(mtHotelGoodsUpDownLog);
                                                                nextCheck = false;
                                                            }else if(thisNewGoodsNewBfNum<hasBreakfastValueIsNum){
                                                                SendUtils.dingMsgNotLog("[FAIL-BREAKFAST-NUM]","该产品早餐数量小于上架时早餐数量，列入失效产品队列，等待消费处理，酒店id="+thisMtHotelId+" 产品id="+thisGoodsId,MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);
                                                                log.info("存在早餐信息变化产品该产品早餐数量小于上架时早餐数量 hotelid={},hasBreakfastValueIsNum={}，thisNewGoodsNewBfNum={}",thisMtHotelId,hasBreakfastValueIsNum,thisNewGoodsNewBfNum);
                                                                //早餐从免费变为 无早餐或者收费早餐，加入失效产品队列--》2020-11-24 携程早餐接口 单无双早都不给设置，相当于无效接口，后期不推送早餐修改。
                                                                breakfastMap.put(thisGoodsId,thisGoodsId);
                                                                MtHotelGoodsUpDownLog mtHotelGoodsUpDownLog = new MtHotelGoodsUpDownLog();
                                                                mtHotelGoodsUpDownLog.setId(StringUtil.getUUID());
                                                                mtHotelGoodsUpDownLog.setMtHotelId(thisMtHotelId);
                                                                mtHotelGoodsUpDownLog.setMtGoodsId(thisGoodsId);
                                                                mtHotelGoodsUpDownLog.setMtRoomId(thisRealRoomId);
                                                                mtHotelGoodsUpDownLog.setRemark("old="+hasBreakfastValueIsNum+",new="+thisNewGoodsNewBfNum+",thisGoodsSwExsiRoomId="+thisGoodsSwExsiRoomId);
                                                                mtHotelGoodsUpDownLog.setCreateTime(new Date());
                                                                mtHotelGoodsUpDownLog.setSource("7");
                                                                mtHotelGoodsUpDownLog.setType("0");
                                                                mtHotelGoodsUpDownLogMapper.insert(mtHotelGoodsUpDownLog);
                                                                nextCheck = false;
                                                            }
                                                        }else if(null != noBreakfastValueIsNum){
                                                            if(1 == thisNewGoodsNewBfType){//有免费早餐
                                                                SendUtils.dingMsgNotLog("[FAIL-BREAKFAST-HAVE]","该产品从无早变为有免费早餐，列入失效产品队列等待携程重新拉取上架，等待POP推送，酒店id="+thisMtHotelId+" 产品id="+thisGoodsId,MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);
                                                                log.info("该产品从无早变为有免费早餐 hotelid={},thisNewGoodsBreakfastVos={}",thisMtHotelId,GsonUtils.GsonString(thisNewGoodsBreakfastVos));
                                                                //早餐从免费变为 无早餐或者收费早餐，加入失效产品队列--》2020-11-24 携程早餐接口 单无双早都不给设置，相当于无效接口，后期不推送早餐修改。
                                                                breakfastMap.put(thisGoodsId,thisGoodsId);
                                                                MtHotelGoodsUpDownLog mtHotelGoodsUpDownLog = new MtHotelGoodsUpDownLog();
                                                                mtHotelGoodsUpDownLog.setId(StringUtil.getUUID());
                                                                mtHotelGoodsUpDownLog.setMtHotelId(thisMtHotelId);
                                                                mtHotelGoodsUpDownLog.setMtGoodsId(thisGoodsId);
                                                                mtHotelGoodsUpDownLog.setMtRoomId(thisRealRoomId);
                                                                mtHotelGoodsUpDownLog.setRemark("old="+0+",new="+thisNewGoodsNewBfType+",thisGoodsSwExsiRoomId="+thisGoodsSwExsiRoomId);
                                                                mtHotelGoodsUpDownLog.setCreateTime(new Date());
                                                                mtHotelGoodsUpDownLog.setSource("8");
                                                                mtHotelGoodsUpDownLog.setType("0");
                                                                mtHotelGoodsUpDownLogMapper.insert(mtHotelGoodsUpDownLog);
                                                                nextCheck = false;

                                                            }

                                                        }
                                                    }
                                                }
                                            }
                                            if(null == redisService.get("PartTimeSwitchsPopQueueFailureGoodsJob_cancel_close")){
                                                if(null != cancelRules && cancelRules.size()>0){
                                                    //校验取消规则，有变动的push到队列，等待job进行推送给携程更新取消规则
                                                    /*携程代码://不可取消
                                                    if(mtHotelGoodsCancelRuleVo.getMtCancelType()==0){
                                                        key=CommonConstants.SWITCH_CREATE_ROOM_CANCEL_RULE+mtHotelId+"_"+mtHotelGoodsDto.getMtGoodsId()+"_0";
                                                        redisService.set(key,"0");
                                                    }else{
                                                        key=CommonConstants.SWITCH_CREATE_ROOM_CANCEL_RULE+mtHotelId+"_"+mtHotelGoodsDto.getMtGoodsId()+"_1";
                                                        String time="";
                                                        time=mtHotelGoodsCancelRuleVo.getMtAheadCancelDays()+"_"+mtHotelGoodsCancelRuleVo.getMtAheadCancelHours();
                                                        redisService.set(key,time);
                                                    }*/
                                                    MtHotelGoodsCancelRuleVo c = cancelRules.get(0);
                                                    String hours = c.getAheadCancelHours();
                                                    Integer type = c.getCancelType();
                                                    Integer days = c.getAheadCancelDays();
                                                    String noCancel = null;//CommonConstants.SWITCH_CREATE_ROOM_CANCEL_RULE+thisMtHotelId+"_"+thisGoodsId+"_0";
                                                    String canCancel = null;//CommonConstants.SWITCH_CREATE_ROOM_CANCEL_RULE+thisMtHotelId+"_"+thisGoodsId+"_1";

                                                    String cancelNoOrYes = (String)redisService.hmGet(CommonConstants.SWITCH_CREATE_ROOM_CANCEL_RULE,thisMtHotelId+"_"+thisGoodsId);
                                                    if(!ObjectUtils.isEmpty(cancelNoOrYes)){
                                                        if(cancelNoOrYes.equals("0")){
                                                            noCancel = "0";
                                                        }else if(cancelNoOrYes.equals("1")){
                                                            canCancel = "1";
                                                        }
                                                        //log.info("进入第二版 取消规则：noCancel={}，canCancel={}",noCancel,canCancel);
                                                    }else{
                                                        noCancel = (String)redisService.get(CommonConstants.SWITCH_CREATE_ROOM_CANCEL_RULE+thisMtHotelId+"_"+thisGoodsId+"_0");
                                                        canCancel = (String)redisService.get(CommonConstants.SWITCH_CREATE_ROOM_CANCEL_RULE+thisMtHotelId+"_"+thisGoodsId+"_1");
                                                        //log.info("进入第一版 取消规则：noCancel={}，canCancel={}",noCancel,canCancel);
                                                    }

                                                    String daysAndHours = String.valueOf(days)+"_"+hours;
                                                    if(null != noCancel && type==1){
                                                        MtfpHotelGoodsCancelRuleVo swc = new MtfpHotelGoodsCancelRuleVo();
                                                        swc.setMtHotelId(thisMtHotelId);
                                                        swc.setMtRoomId(thisGoodsSwExsiRoomId);
                                                        swc.setMtGoodsId(thisGoodsId);
                                                        swc.setAheadCancelDays(days);
                                                        swc.setAheadCancelHours(hours);
                                                        swc.setCancelType(type);
                                                        swc.setDeductType(c.getDeductType());
                                                        //原本的不可取消，发生了改变
                                                        redisService.lPush(CallbackConstants.REDIS_SWMT_QUEUE_CHANGE_CANCEL_GOODS,GsonUtils.GsonString(swc));
                                                        SendUtils.dingMsgNotLog("[CANCEL-CHECK-CHANGE-YES] 上架产品取消规则变化为允许取消 "," 酒店id="+thisMtHotelId+" 产品id="+thisGoodsId+" cancel信息="+GsonUtils.GsonString(cancelRules),MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);
                                                        log.info("上架产品取消规则变化为允许取消 hotelid={},goodsId={}, thisGoodsSwExsiRoomId={},goodsBaseInfoVo.thisRealRoomId()={}",thisMtHotelId,thisGoodsId,thisGoodsSwExsiRoomId,thisRealRoomId);
                                                        changeRGoods.put(thisGoodsId,thisGoodsId);
                                                        MtHotelGoodsUpDownLog mtHotelGoodsUpDownLog = new MtHotelGoodsUpDownLog();
                                                        mtHotelGoodsUpDownLog.setId(StringUtil.getUUID());
                                                        mtHotelGoodsUpDownLog.setMtHotelId(thisMtHotelId);
                                                        mtHotelGoodsUpDownLog.setMtGoodsId(thisGoodsId);
                                                        mtHotelGoodsUpDownLog.setMtRoomId(thisRealRoomId);
                                                        mtHotelGoodsUpDownLog.setCreateTime(new Date());
                                                        mtHotelGoodsUpDownLog.setRemark("yes,cancel信息："+GsonUtils.GsonString(cancelRules)+"，缓存="+noCancel);
                                                        mtHotelGoodsUpDownLog.setSource("12");
                                                        mtHotelGoodsUpDownLog.setType("3");
                                                        mtHotelGoodsUpDownLogMapper.insert(mtHotelGoodsUpDownLog);
                                                    }else if(null != canCancel && type==0){
                                                        MtfpHotelGoodsCancelRuleVo swc = new MtfpHotelGoodsCancelRuleVo();
                                                        swc.setMtHotelId(thisMtHotelId);
                                                        swc.setMtRoomId(thisGoodsSwExsiRoomId);
                                                        swc.setMtGoodsId(thisGoodsId);
                                                        swc.setAheadCancelDays(days);
                                                        swc.setAheadCancelHours(hours);
                                                        swc.setCancelType(type);
                                                        swc.setDeductType(c.getDeductType());
                                                        //原本是可取消发生改变为不可取消
                                                        redisService.lPush(CallbackConstants.REDIS_SWMT_QUEUE_CHANGE_CANCEL_GOODS,GsonUtils.GsonString(swc));
                                                        SendUtils.dingMsgNotLog("[CANCEL-CHECK-CHANGE-NO] 上架产品取消规则变化为不可取消 "," 酒店id="+thisMtHotelId+" 产品id="+thisGoodsId+" cancel信息="+GsonUtils.GsonString(cancelRules),MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);
                                                        log.info("上架产品取消规则变化为不可取消 hotelid={},goodsId={}, thisGoodsSwExsiRoomId={},goodsBaseInfoVo.thisRealRoomId()={}",thisMtHotelId,thisGoodsId,thisGoodsSwExsiRoomId,thisRealRoomId);
                                                        changeRGoods.put(thisGoodsId,thisGoodsId);
                                                        MtHotelGoodsUpDownLog mtHotelGoodsUpDownLog = new MtHotelGoodsUpDownLog();
                                                        mtHotelGoodsUpDownLog.setId(StringUtil.getUUID());
                                                        mtHotelGoodsUpDownLog.setMtHotelId(thisMtHotelId);
                                                        mtHotelGoodsUpDownLog.setMtGoodsId(thisGoodsId);
                                                        mtHotelGoodsUpDownLog.setMtRoomId(thisRealRoomId);
                                                        mtHotelGoodsUpDownLog.setCreateTime(new Date());
                                                        mtHotelGoodsUpDownLog.setRemark("no,cancel信息："+GsonUtils.GsonString(cancelRules)+"，缓存="+redisService.get(canCancel));
                                                        mtHotelGoodsUpDownLog.setSource("12");
                                                        mtHotelGoodsUpDownLog.setType("3");
                                                        mtHotelGoodsUpDownLogMapper.insert(mtHotelGoodsUpDownLog);
                                                    }else if(null != canCancel && !daysAndHours.equals(canCancel)){//允许取消但是时间规则发生改变
                                                        MtfpHotelGoodsCancelRuleVo swc = new MtfpHotelGoodsCancelRuleVo();
                                                        swc.setMtHotelId(thisMtHotelId);
                                                        swc.setMtRoomId(thisGoodsSwExsiRoomId);
                                                        swc.setMtGoodsId(thisGoodsId);
                                                        swc.setAheadCancelDays(days);
                                                        swc.setAheadCancelHours(hours);
                                                        swc.setCancelType(type);
                                                        swc.setDeductType(c.getDeductType());
                                                        //原本是可取消发生改变为不可取消
                                                        redisService.lPush(CallbackConstants.REDIS_SWMT_QUEUE_CHANGE_CANCEL_GOODS,GsonUtils.GsonString(swc));
                                                        SendUtils.dingMsgNotLog("[CANCEL-CHECK-CHANGE-INFO] 上架产品允许取消但是时间规则发生改变 ",DateUtil.getCurrTime()+" 酒店id="+thisMtHotelId+" 产品id="+thisGoodsId+" cancel信息="+GsonUtils.GsonString(cancelRules),MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);
                                                        log.info("上架产品允许取消但是时间规则发生改变 hotelid={},goodsId={}, thisGoodsSwExsiRoomId={},goodsBaseInfoVo.thisRealRoomId()={}",thisMtHotelId,thisGoodsId,thisGoodsSwExsiRoomId,thisRealRoomId);
                                                        changeRGoods.put(thisGoodsId,thisGoodsId);
                                                        MtHotelGoodsUpDownLog mtHotelGoodsUpDownLog = new MtHotelGoodsUpDownLog();
                                                        mtHotelGoodsUpDownLog.setId(StringUtil.getUUID());
                                                        mtHotelGoodsUpDownLog.setMtHotelId(thisMtHotelId);
                                                        mtHotelGoodsUpDownLog.setMtGoodsId(thisGoodsId);
                                                        mtHotelGoodsUpDownLog.setMtRoomId(thisRealRoomId);
                                                        mtHotelGoodsUpDownLog.setCreateTime(new Date());
                                                        mtHotelGoodsUpDownLog.setRemark("info,cancel信息："+GsonUtils.GsonString(cancelRules)+"，缓存="+canCancel);
                                                        mtHotelGoodsUpDownLog.setSource("12");
                                                        mtHotelGoodsUpDownLog.setType("3");
                                                        mtHotelGoodsUpDownLogMapper.insert(mtHotelGoodsUpDownLog);
                                                    }
                                                }
                                            }

                                        }
                                    }else{
                                        //SendUtils.dingMsgNotLog("[ROOM-NULL] 上架产品未正常查询到房型，realRoomId为null，归列到失效产品！ "," 酒店id="+thisMtHotelId+" 产品id="+thisGoodsId+" room信息="+GsonUtils.GsonString(thisGoodsRoomInfoArr),MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);
                                        log.info("上架产品未正常查询到realRoomId为null归列到失效产品 hotelid={},goodsId={}, thisGoodsSwExsiRoomId={},goodsBaseInfoVo.thisRealRoomId()={}",thisMtHotelId,thisGoodsId,thisGoodsSwExsiRoomId,thisRealRoomId);
                                        changeRGoods.put(thisGoodsId,thisGoodsId);
                                        MtHotelGoodsUpDownLog mtHotelGoodsUpDownLog = new MtHotelGoodsUpDownLog();
                                        mtHotelGoodsUpDownLog.setId(StringUtil.getUUID());
                                        mtHotelGoodsUpDownLog.setMtHotelId(thisMtHotelId);
                                        mtHotelGoodsUpDownLog.setMtGoodsId(thisGoodsId);
                                        mtHotelGoodsUpDownLog.setMtRoomId(thisRealRoomId);
                                        mtHotelGoodsUpDownLog.setCreateTime(new Date());
                                        mtHotelGoodsUpDownLog.setRemark("产品接口返回room信息："+GsonUtils.GsonString(thisHotelOneGoodsInfo)+"，缓存roomid="+thisGoodsSwExsiRoomId);
                                        mtHotelGoodsUpDownLog.setSource("5");
                                        mtHotelGoodsUpDownLog.setType("0");
                                        mtHotelGoodsUpDownLogMapper.insert(mtHotelGoodsUpDownLog);
                                    }
                                }

                            }else{
                                log.error("获取酒店信息room信息为空为空！！"+GsonUtils.GsonString(hotelDetail));
                            }

                        }
                        //额外字段
                        thisHotelOneGoodsInfo.setMtCityId(thisGoodsRoomInfoArr.get(0).getCityId());
                        thisHotelOneGoodsInfo.setMtRoomName(thisGoodsRoomInfoArr.get(0).getRoomName());
                    }
                    newThisHotelGoodsRoomInfoMap.put(thisGoodsId,thisHotelOneGoodsInfo.getRoomId());//最终roomid thisHotelOneGoodsInfo.getRoomId()
                    newOneHotelOneGoodsMap.put(thisHotelOneGoodsInfo.getHotelId()+"_"+thisGoodsId,thisHotelOneGoodsInfo);
                }else{
                    //遍历携程上架酒店产品
                    if(null != thisGoodsSwExsiRoomId){
                        if(null != thisOneSwHotelGoodsMapData.get(thisGoodsId)){
                            log.error("findMtGoodsCheckUpDown   该产品非全日房：thisMtHotelId={},getGoodsId={},goodsType={}",thisMtHotelId,thisGoodsId,thisGoodsType);
                            //上架的产品被变为非全日房了
                            notFullDayGoodsMap.put(thisGoodsId,thisGoodsId);
                            MtHotelGoodsUpDownLog mtHotelGoodsUpDownLog = new MtHotelGoodsUpDownLog();
                            mtHotelGoodsUpDownLog.setId(StringUtil.getUUID());
                            mtHotelGoodsUpDownLog.setMtHotelId(thisMtHotelId);
                            mtHotelGoodsUpDownLog.setMtGoodsId(thisGoodsId);
                            mtHotelGoodsUpDownLog.setMtRoomId(GsonUtils.GsonString(thisHotelOneGoodsInfo.getRoomInfoList()));
                            mtHotelGoodsUpDownLog.setRemark(""+thisGoodsType);
                            mtHotelGoodsUpDownLog.setCreateTime(new Date());
                            mtHotelGoodsUpDownLog.setSource("3");
                            mtHotelGoodsUpDownLog.setType("0");
                            mtHotelGoodsUpDownLogMapper.insert(mtHotelGoodsUpDownLog);
                        }
                    }
                }
            }

        }

        if(null != changeRGoods && changeRGoods.size()>0){
            log.info("该酒店存在房型id变更产品：{},酒店id={}",GsonUtils.GsonString(changeRGoods),thisMtHotelId);
            //SendUtils.dingMsgNotLog("[CHANGE-ERROR] 该酒店存在房型id变更产品 ",DateUtil.getCurrTime()+" 将push到失效产品队列，等待消费pop："+GsonUtils.GsonString(changeRGoods)+" 酒店id："+thisMtHotelId,MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);
        }
        if(null != breakfastMap && breakfastMap.size()>0){
            log.info("存在产品早餐变动，将push到失效产品队列，等待消费pop："+GsonUtils.GsonString(breakfastMap));
            //SendUtils.dingMsgNotLog("[FULL-ERROR] 该酒店存在上架产品早餐变动 ",DateUtil.getCurrTime()+" 将push到失效产品队列，等待消费pop："+GsonUtils.GsonString(breakfastMap)+" 酒店id："+thisMtHotelId,MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);
        }
        if(null != idcardmap && idcardmap.size()>0){
            log.info("需要身份证产品，将push到失效产品队列，等待消费pop："+GsonUtils.GsonString(idcardmap));
            //SendUtils.dingMsgNotLog("[FULL-ERROR] 该酒店存在上架产品需要身份证 ",DateUtil.getCurrTime()+" 将push到失效产品队列，等待消费pop："+GsonUtils.GsonString(idcardmap)+" 酒店id："+thisMtHotelId,MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);
        }
        if(null != notFullDayGoodsMap && notFullDayGoodsMap.size()>0){
            log.info("存在产品是全日房变更为钟点房，将push到失效产品队列，等待消费pop："+GsonUtils.GsonString(notFullDayGoodsMap));
            //SendUtils.dingMsgNotLog("[FULL-ERROR] 该酒店存在上架产品是全日房变更为钟点房 ",DateUtil.getCurrTime()+" 将push到失效产品队列，等待消费pop："+GsonUtils.GsonString(notFullDayGoodsMap)+" 酒店id："+thisMtHotelId,MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);
        }



    }

    /**
     *  该酒店查无产品即该酒店所有产品已失效
     * @param thisOneSwHotelGoodsInfoMap
     * @param swHotelId
     * @param timestampIndex
     */
    public void oneHotelNoneGoodsBuildQueueFailVo(Map<String,String> thisOneSwHotelGoodsInfoMap,String swHotelId,String timestampIndex){

        ProductFailureVo oneHotelAllProductFailureVo = new ProductFailureVo();//每次队列一个该酒店vo
        List<ProductFailureDetailVo> thisHotelAllGoodsDataFailVo = new ArrayList<>();
        oneHotelAllProductFailureVo.setMtHotelId(Integer.valueOf(swHotelId));

        //遍历该酒店上架产品
        for (Map.Entry upGoodsId:thisOneSwHotelGoodsInfoMap.entrySet()){
            //构建队列需要产品vo
            String goodsId = (String)upGoodsId.getKey();
            String roomId = (String)upGoodsId.getValue();
            ProductFailureDetailVo detailVo = buildOneGoodsFailureDetailVoSaveLog(goodsId,roomId,swHotelId,"1");
            thisHotelAllGoodsDataFailVo.add(detailVo);
        }
        oneHotelAllProductFailureVo.setGoods(thisHotelAllGoodsDataFailVo);//失效产品集合set到该酒店vo中

        pushSwQueue(swHotelId,GsonUtils.GsonString(oneHotelAllProductFailureVo),timestampIndex);

    }

    public ProductFailureDetailVo buildOneGoodsFailureDetailVoSaveLog(String goodsId,String roomId,String swHotelId,String source){
        ProductFailureDetailVo detailVo = new ProductFailureDetailVo();
        detailVo.setGenre(0);
        detailVo.setMtGoodId(Integer.valueOf(goodsId));
        detailVo.setMtRoomId(Integer.valueOf(roomId));

        MtHotelGoodsUpDownLog mtHotelGoodsUpDownLog = new MtHotelGoodsUpDownLog();
        mtHotelGoodsUpDownLog.setId(StringUtil.getUUID());
        mtHotelGoodsUpDownLog.setCreateTime(new Date());
        mtHotelGoodsUpDownLog.setMtHotelId(String.valueOf(swHotelId));
        mtHotelGoodsUpDownLog.setMtRoomId(roomId);
        mtHotelGoodsUpDownLog.setMtGoodsId(goodsId);
        mtHotelGoodsUpDownLog.setType("0");
        mtHotelGoodsUpDownLog.setSource(source);
        try {
            mtHotelGoodsUpDownLogMapper.insert(mtHotelGoodsUpDownLog);
        }catch (Exception e){
            log.error("checkHotelGoodsFail  mtHotelGoodsUpDownLogMapper保存失败 593");
            e.printStackTrace();
        }
        return detailVo;
    }

    private void pushSwQueue(String thisMtHotelId,String productFailureVoJSON,String timestampIndex) {
        //推送携程
        log.info(timestampIndex+" findMtGoodsCheckUpDown  当前酒店推送携程：mtHotelId={},参数：{}",thisMtHotelId,productFailureVoJSON);

        redisService.lPush(MeituanConstants.REDIS_QUEUE_HOTEL_DOWN_GOODS_JSON_KEY,productFailureVoJSON);
        log.info(timestampIndex+" findMtGoodsCheckUpDown 发现失效产品 追加到队列中：当前队列size={}",redisService.queueSize(MeituanConstants.REDIS_QUEUE_HOTEL_DOWN_GOODS_JSON_KEY));
    }

    /**
     * 2、对比本地库表，校验产品是否存在新增
     * @param thisMtHotelId
     * @param newThisHotelGoodsRoomInfoMap
     * @param newOneHotelOneGoodsMap
     * @param addCount
     * @param addGoods
     * @param bfCount
     * @param bfGoods
     * @param timestampIndex
     */
    private void checkLocalDataIsAddProductPushQueue(String thisMtHotelId,Map<String,String> newThisHotelGoodsRoomInfoMap,Map<String,MtHotelGoodsBaseInfoVo> newOneHotelOneGoodsMap,
                                                     Integer addCount,List<String> addGoods,int bfCount,List<String> bfGoods,String timestampIndex) {
        log.info("对比本地库表，checkLocalDataIsAddProductPushQueue");
        //获取库表中该酒店产品数据
        Example example = new Example(MtHotelDetail.class);
        example.createCriteria().andEqualTo("mtHotelId", thisMtHotelId);
        List<MtHotelGoods> thisHotelLocalGoods = mtHotelGoodsMapper.selectByExample(example);
        if(null != thisHotelLocalGoods && thisHotelLocalGoods.size()>0){

            PushHotelBreakfastVo thisHotelBreakfastVo = new PushHotelBreakfastVo();
            thisHotelBreakfastVo.setMtHotelId(Integer.valueOf(thisMtHotelId));
            List<PushHotelBreakfastDetailVo> thisHotelGoodsBrearkfastDetailsVo = new ArrayList<>();

            Map<String,String> localGoodsMap = new HashMap<>();
            for (MtHotelGoods g:thisHotelLocalGoods){
                localGoodsMap.put(g.getMtGoodsId(),g.getMtGoodsId());
            }
            Map<String, List<MtHotelGoodsDto>> roomAboutgoodsDtosMap = new HashMap<>();
            for (Map.Entry g:newThisHotelGoodsRoomInfoMap.entrySet()){
                String newGoodsId = (String)g.getKey();
                String newRoomId = (String)g.getValue();
                MtHotelGoodsBaseInfoVo mtHotelGoodsBaseInfoVo = newOneHotelOneGoodsMap.get(thisMtHotelId+"_"+newGoodsId);
                //遍历新查到的产品信息  比对
                if(null == localGoodsMap.get(newGoodsId)){
                    //最新产品不在本地库，则为新增
                    addCount +=1;
                    addGoods.add(newGoodsId);
                    log.info("findMtGoodsCheckUpDown 符合为新增产品 hotelId={},newGoodsId={},newRoomId={}",thisMtHotelId,newGoodsId,newRoomId);
                    MtHotelGoodsUpDownLog mtHotelGoodsUpDownLog = new MtHotelGoodsUpDownLog();
                    mtHotelGoodsUpDownLog.setId(StringUtil.getUUID());
                    mtHotelGoodsUpDownLog.setCreateTime(new Date());
                    mtHotelGoodsUpDownLog.setMtHotelId(String.valueOf(thisMtHotelId));
                    mtHotelGoodsUpDownLog.setMtRoomId(String.valueOf(newRoomId));
                    mtHotelGoodsUpDownLog.setMtGoodsId(String.valueOf(newGoodsId));
                    mtHotelGoodsUpDownLog.setType("1");
                    try {
                        mtHotelGoodsUpDownLogMapper.insert(mtHotelGoodsUpDownLog);
                    }catch (Exception e){
                        log.error("findMtGoodsCheckUpDown  mtHotelGoodsUpDownLogMapper保存失败 1228");
                        e.printStackTrace();
                    }
                    if(null != mtHotelGoodsBaseInfoVo){
                        //构建数据
                        List<MtHotelGoodsDto> mtHotelGoodsDtos = roomAboutgoodsDtosMap.get(newRoomId);
                        if(null == mtHotelGoodsDtos || mtHotelGoodsDtos.size()==0){
                            mtHotelGoodsDtos = new ArrayList<>();
                        }
                        MtHotelGoodsDto mtHotelGoodsDtoOne = new MtHotelGoodsDto();
                        mtHotelGoodsDtoOne.setMtHotelId(String.valueOf(thisMtHotelId));
                        mtHotelGoodsDtoOne.setMtRoomId(mtHotelGoodsBaseInfoVo.getRoomId());
                        mtHotelGoodsDtoOne.setMtGoodsId(mtHotelGoodsBaseInfoVo.getGoodsId());
                        mtHotelGoodsDtoOne.setMtCityId(mtHotelGoodsBaseInfoVo.getMtCityId());
                        mtHotelGoodsDtoOne.setMtRoomName(mtHotelGoodsBaseInfoVo.getMtRoomName());
                        mtHotelGoodsDtoOne.setMtGoodsName(mtHotelGoodsBaseInfoVo.getGoodsName());
                        mtHotelGoodsDtoOne.setMtNeedRealTel(mtHotelGoodsBaseInfoVo.getNeedRealTel());
                        mtHotelGoodsDtoOne.setMtGoodsStatus(mtHotelGoodsBaseInfoVo.getGoodsStatus());
                        mtHotelGoodsDtoOne.setMtGoodsType(mtHotelGoodsBaseInfoVo.getGoodsType());
                        mtHotelGoodsDtoOne.setMtAveragePrice(mtHotelGoodsBaseInfoVo.getAveragePrice());
                        mtHotelGoodsDtoOne.setMtOriginalPrice(mtHotelGoodsBaseInfoVo.getOriginalPrice());
                        mtHotelGoodsDtoOne.setMtThirdParty(mtHotelGoodsBaseInfoVo.getThirdParty());
                        mtHotelGoodsDtoOne.setMtConfirmType(mtHotelGoodsBaseInfoVo.getConfirmType());
                        mtHotelGoodsDtoOne.setMtNeedIdentityCard(mtHotelGoodsBaseInfoVo.getNeedIdentityCard()==true?1:2);
                        mtHotelGoodsDtoOne.setMtPaymentType(mtHotelGoodsBaseInfoVo.getPaymentType());
                        List<MtHotelGoodsBreakfastVo> breakFast = mtHotelGoodsBaseInfoVo.getBreakFast();
                        if(null != breakFast && breakFast.size()>0){
                            List<MtHotelGoodsBreakfastDto> breakfastList = new ArrayList<>();
                            for (MtHotelGoodsBreakfastVo v:breakFast){
                                MtHotelGoodsBreakfastDto mtHotelGoodsBreakfastDto = new MtHotelGoodsBreakfastDto();
                                mtHotelGoodsBreakfastDto.setMtHotelId(String.valueOf(thisMtHotelId));
                                mtHotelGoodsBreakfastDto.setMtRoomId(mtHotelGoodsBaseInfoVo.getRoomId());
                                mtHotelGoodsBreakfastDto.setMtGoodsId(mtHotelGoodsBaseInfoVo.getGoodsId());
                                mtHotelGoodsBreakfastDto.setMtBreakfastNum(v.getBreakfastNum());
                                mtHotelGoodsBreakfastDto.setMtBreakfastType(v.getBreakfastType());
                                mtHotelGoodsBreakfastDto.setMtStartDate(String.valueOf(v.getInStartDate()));
                                mtHotelGoodsBreakfastDto.setMtEndDate(String.valueOf(v.getInEndDate()));
                                breakfastList.add(mtHotelGoodsBreakfastDto);
                            }
                            mtHotelGoodsDtoOne.setBreakfastList(breakfastList);
                        }
                        List<MtHotelGoodsCancelRuleVo> cancelListVo = mtHotelGoodsBaseInfoVo.getCancelRules();
                        if(null != cancelListVo && cancelListVo.size()>0){
                            List<MtHotelGoodsCancelRuleDto> cancelListDto = new ArrayList<>();
                            for (MtHotelGoodsCancelRuleVo v:cancelListVo){
                                MtHotelGoodsCancelRuleDto mtHotelGoodsCancelRuleDto = new MtHotelGoodsCancelRuleDto();
                                mtHotelGoodsCancelRuleDto.setMtHotelId(String.valueOf(thisMtHotelId));
                                mtHotelGoodsCancelRuleDto.setMtRoomId(mtHotelGoodsBaseInfoVo.getRoomId());
                                mtHotelGoodsCancelRuleDto.setMtGoodsId(mtHotelGoodsBaseInfoVo.getGoodsId());
                                mtHotelGoodsCancelRuleDto.setMtCancelType(v.getCancelType());
                                mtHotelGoodsCancelRuleDto.setMtDeductType(v.getDeductType());
                                mtHotelGoodsCancelRuleDto.setMtAheadCancelDays(v.getAheadCancelDays());
                                mtHotelGoodsCancelRuleDto.setMtAheadCancelHours(v.getAheadCancelHours());
                                cancelListDto.add(mtHotelGoodsCancelRuleDto);
                            }
                            mtHotelGoodsDtoOne.setCancelRuleList(cancelListDto);
                        }
                        List<MtHotelGoodsBookRuleVo> bookRulesListVo = mtHotelGoodsBaseInfoVo.getBookRules();
                        if(null != bookRulesListVo && bookRulesListVo.size()>0){
                            List<MtHotelGoodsBookRuleDto> bookRuleListDto = new ArrayList<>();
                            for (MtHotelGoodsBookRuleVo v:bookRulesListVo){
                                MtHotelGoodsBookRuleDto mtHotelGoodsBookRuleDto = new MtHotelGoodsBookRuleDto();
                                mtHotelGoodsBookRuleDto.setMtHotelId(String.valueOf(thisMtHotelId));
                                mtHotelGoodsBookRuleDto.setMtRoomId(mtHotelGoodsBaseInfoVo.getRoomId());
                                mtHotelGoodsBookRuleDto.setMtGoodsId(mtHotelGoodsBaseInfoVo.getGoodsId());
                                mtHotelGoodsBookRuleDto.setMtInEndDate(v.getInEndDate());
                                mtHotelGoodsBookRuleDto.setMtInStartDate(v.getInStartDate());
                                mtHotelGoodsBookRuleDto.setMtEarliestBookingDays(v.getEarliestBookingDays());
                                mtHotelGoodsBookRuleDto.setMtEarliestBookingHours(v.getEarliestBookingHours());
                                mtHotelGoodsBookRuleDto.setMtLatestBookingDays(v.getLatestBookingDays());
                                mtHotelGoodsBookRuleDto.setMtLatestBookingHours(v .getLatestBookingHours());
                                mtHotelGoodsBookRuleDto.setMtIsDaybreakBooking(v.getIsDaybreakBooking());
                                mtHotelGoodsBookRuleDto.setMtSerialCheckinMax(v.getSerialCheckinMax());
                                mtHotelGoodsBookRuleDto.setMtSerialCheckinMin(v.getSerialCheckinMin());
                                mtHotelGoodsBookRuleDto.setMtRoomCountMax(v.getRoomCountMax());
                                mtHotelGoodsBookRuleDto.setMtRoomCountMin(v.getRoomCountMin());
                                bookRuleListDto.add(mtHotelGoodsBookRuleDto);

                            }
                            mtHotelGoodsDtoOne.setBookRuleList(bookRuleListDto);
                        }

                        MtHotelInvoiceInfoVo invoiceVo = mtHotelGoodsBaseInfoVo.getInvoiceInfo();
                        if(null != invoiceVo){
                            MtHotelGoodsInvoiceDto mtHotelGoodsInvoiceDto = new MtHotelGoodsInvoiceDto();
                            mtHotelGoodsInvoiceDto.setInvoiceMode(invoiceVo.getInvoiceMode());
                            mtHotelGoodsInvoiceDto.setSupportTypes(String.valueOf(invoiceVo.getSupportTypes()));
                            mtHotelGoodsInvoiceDto.setTmcInvoiceMode(invoiceVo.getTmcInvoiceMode());
                            mtHotelGoodsDtoOne.setInvoice(mtHotelGoodsInvoiceDto);
                        }

                        mtHotelGoodsDtos.add(mtHotelGoodsDtoOne);
                        roomAboutgoodsDtosMap.put(thisMtHotelId+"_"+String.valueOf(newRoomId),mtHotelGoodsDtos);

                    }else{
                        log.error("findMtGoodsCheckUpDown  判断为新增产品但 该产品没有数据：美团酒店id={}，newGoodsId={}",thisMtHotelId,newGoodsId);
                    }
                }else{
                    //该产品存在在本地库，为产品校验早餐信息，push到更新早餐信息队列中，后面定时器消费队列推送携程，飞猪
                    /*if(null != mtHotelGoodsBaseInfoVo){=========================>>>>由于携程接口早餐接口不接收，当前注释  2020-11-24
                        //该产品的早餐信息，推送给携程飞猪，按酒店为单位
                        List<MtHotelGoodsBreakfastVo> thisNewGoodsBreakfastVos = mtHotelGoodsBaseInfoVo.getBreakFast();
                        if(null != thisNewGoodsBreakfastVos && thisNewGoodsBreakfastVos.size()>0){
                            //获取本地库最新的一条早餐信息，比对（正常来说一个产品对应一条早餐信息）
                            Map map = new HashMap();
                            map.put("mtHotelId",thisMtHotelId);
                            map.put("mtGoodsId",newGoodsId);
                            MtHotelGoodsBreakfast thisOldGoodsBreakfastLocal = mtHotelGoodsBreakfastMapper.getTopBreakfastByGoodsIdHotelId(map);
                            if(null != thisOldGoodsBreakfastLocal){
                                Integer thisNewGoodsNewBfNum = thisNewGoodsBreakfastVos.get(0).getBreakfastNum();
                                Integer thisNewGoodsNewBfType = thisNewGoodsBreakfastVos.get(0).getBreakfastType();

                                if((thisOldGoodsBreakfastLocal.getMtBreakfastNum()!= thisNewGoodsNewBfNum) || (thisOldGoodsBreakfastLocal.getMtBreakfastType() != thisNewGoodsNewBfType)){
                                    log.info("存在早餐信息变化产品 hotelid={},thisOldGoodsBreakfastLocal={},thisNewGoodsBreakfastVos={}",thisMtHotelId,GsonUtils.GsonString(thisOldGoodsBreakfastLocal),GsonUtils.GsonString(thisNewGoodsBreakfastVos));
                                    //构建一个产品早餐vo
                                    PushHotelBreakfastDetailVo pushHotelBreakfastDetailVo = new PushHotelBreakfastDetailVo();
                                    pushHotelBreakfastDetailVo.setGoodsId(newGoodsId);
                                    List<MtHotelGoodsBreakfastVo> breakFast = new ArrayList<>();
                                    MtHotelGoodsBreakfastVo mtHotelGoodsBreakfastVo = new MtHotelGoodsBreakfastVo();
                                    mtHotelGoodsBreakfastVo.setBreakfastNum(thisNewGoodsNewBfNum);
                                    mtHotelGoodsBreakfastVo.setBreakfastType(thisNewGoodsNewBfType);
                                    mtHotelGoodsBreakfastVo.setInEndDate(thisNewGoodsBreakfastVos.get(0).getInEndDate());
                                    mtHotelGoodsBreakfastVo.setInStartDate(thisNewGoodsBreakfastVos.get(0).getInStartDate());
                                    breakFast.add(mtHotelGoodsBreakfastVo);
                                    pushHotelBreakfastDetailVo.setBreakFast(breakFast);
                                    bfCount +=1;
                                }
                            }
                        }

                    }*/

                }
            }

            //是否存在早餐变化产品集合，有则push到队列
            if(null != thisHotelGoodsBrearkfastDetailsVo && thisHotelGoodsBrearkfastDetailsVo.size()>0){
                log.info("该酒店存在早餐变化，push到早餐队列size={},thisHotelBreakfastVo={}",thisHotelGoodsBrearkfastDetailsVo.size(),GsonUtils.GsonString(thisHotelBreakfastVo));
                thisHotelBreakfastVo.setGoodsBreakfast(thisHotelGoodsBrearkfastDetailsVo);
                redisService.lPush(MeituanConstants.REDIS_QUEUE_HOTEL_BREAKFAST_JSON_KEY,GsonUtils.GsonString(thisHotelBreakfastVo));
            }

            log.info(timestampIndex+" findMtGoodsCheckUpDown roomAboutgoodsDtosMap={} ",roomAboutgoodsDtosMap.size());
            if(null != roomAboutgoodsDtosMap && roomAboutgoodsDtosMap.size()>0){

                List<MtHotelGoodsDataGroupRoomDto> mtHotelGoodsListDtoArray = new ArrayList<>();
                for (Map.Entry entry:roomAboutgoodsDtosMap.entrySet()){
                    String key_hotelid_roomid = (String)entry.getKey();
                    MtHotelGoodsDataGroupRoomDto mtHotelGoodsDataGroupRoomDto = new MtHotelGoodsDataGroupRoomDto();
                    mtHotelGoodsDataGroupRoomDto.setMtHotelId(key_hotelid_roomid.split("_")[0]);
                    mtHotelGoodsDataGroupRoomDto.setMtRoomId(key_hotelid_roomid.split("_")[1]);
                    mtHotelGoodsDataGroupRoomDto.setMtHotelGoodsDtoData((List<MtHotelGoodsDto>)entry.getValue());
                    mtHotelGoodsListDtoArray.add(mtHotelGoodsDataGroupRoomDto);
                }
                //推送携程
                ProductNewAddVo productNewAddVo = new ProductNewAddVo();
                productNewAddVo.setMtRoomGoodsData(mtHotelGoodsListDtoArray);
                log.info(timestampIndex+" findMtGoodsCheckUpDown   新增 当前酒店推送携程：mtHotelId={},参数：{}",thisMtHotelId,GsonUtils.GsonString(productNewAddVo));

                redisService.lPush(MeituanConstants.REDIS_QUEUE_HOTEL_ADD_GOODS_JSON_KEY,GsonUtils.GsonString(productNewAddVo));
                log.info(timestampIndex+" findMtGoodsCheckUpDown 发现新增产品 追加到队列中：当前队列size={}",redisService.queueSize(MeituanConstants.REDIS_QUEUE_HOTEL_ADD_GOODS_JSON_KEY));
            }

        }else{
            log.error("findMtGoodsCheckUpDown  本地库未找到产品信息：美团酒店id={}",thisMtHotelId);
        }
    }

}
